home *** CD-ROM | disk | FTP | other *** search
- /* DMATransfer.h */
- /*
- * DMATransfer.h
- * Copyright © 1995 Apple Computer Inc. All rights reserved.
- */
- /* .___________________________________________________________________________________.
- | This library simplifies using PrepareMemoryForIO with DMA and non-DMA hardware |
- | devices. These functions can be called from any interrupt level. |
- | |
- | PrepareDMATransfer prepares the next segment (logical or physical) that can |
- | be computed from the current state of the I/O table. The caller must adapt the |
- | result if required maximum transfer length limitations. |
- | |
- | Usage: |
- | while ((myIOTable.state & kIOStateDone) == 0) { |
- | status = PrepareMemoryForIO(&myIOTable); // Do preparation |
- | if (status == noErr) { // Start dma preparation |
- | status = InitializeDMATransfer( |
- | &myIOTable, |
- | myLogicalAlignment, |
- | &myDMATable |
- | ); |
- | while (status == noErr) { // Start dma operation |
- | status = PrepareDMATransfer( |
- | &myDMATable, |
- | &myNextTransfer, |
- | &nextIsLogical |
- | ); |
- | if (status == noErr) { |
- | if (nextIsLogical) |
- | DoLogicalTransfer(&myNextTransfer); |
- | else { |
- | DoPhysicalTransfer(&myNextTransfer); |
- | } |
- | } // For all DMA segments for this preparation. |
- | } // while there is data to transmit |
- | CheckpointIO(myIOTable.preparationID, kNilOptions); |
- | } // if PrepareMemoryForIO succeeded |
- .___________________________________________________________________________________.
- */
-
- #ifndef DMATransfer
- #define DMATransfer
-
- #include <Types.h>
- #include <Kernel.h>
- #include <Errors.h>
-
- struct DMATransferInfo {
- const IOPreparationTable *ioTablePtr; /* Caller's I/O Prep Table */
- UInt32 logicalAlignment; /* Caller's parameter */
- ItemCount scatterGatherIndex; /* 0 to range.entryCount */
- ByteCount prepareCount; /* 0 to lengthPrepared */
- ByteCount rangeCount; /* 0 to range length */
- ByteCount rangeLength; /* Length of this sg area */
- ItemCount physicalMapIndex; /* 0 to mappingEntryCount */
- ByteCount physicalStart; /* 0 to physicalLength */
- ByteCount physicalEnd; /* DMA high-water mark */
- ByteCount firstPageOffset; /* Logical transfer hack */
- AddressRange physicalRange; /* Current physical segment */
- AddressRange logicalStart; /* Initial logical segment */
- AddressRange logicalEnd; /* Final logical segment */
- };
- typedef struct DMATransferInfo DMATransferInfo, *DMATransferInfoPtr;
-
- /* .___________________________________________________________________________________.
- | InitializeDMATransfer |
- | |
- | Initialize the DMATransferInfo record. |
- | Input: |
- | ioTable The prepared I/O Preparation table. It is "ready to run" |
- | logicalGranularity This is a power of two that is used to group the transfer |
- | into logical and physical segments. If zero, only physical |
- | transfers will be reported. If one and a logical segment |
- | begins on an odd-byte boundary, PrepareDMATransfer will |
- | return a one-byte logical transfer, then one or more |
- | physical transfers then, if necessary, a one-byte logical |
- | transfer. |
- | |
- | Output: |
- | dmaTablePtr The DMATransferInfo record that will manage this transfer. |
- | |
- | Result: |
- | noErr Normal. |
- | paramErr Bad parameters (ioTable or dmaTablePtr are NULL or an error |
- | in the IOTable parameters. |
- | |
- | Set the IOTable parameter block as follows: |
- | kIOLogicalRanges Required if non-zero logical granularity. |
- | kIOMinimalLogicalMapping Required if non-zero logical granularity. |
- | mappingEntryCount > 0 |
- | options: |
- | kIOTransferIsLogical Must be FALSE |
- | kIOMinimalLogicalMapping Required |
- | kIOIsInput or kIOIsOutput One is required |
- .___________________________________________________________________________________.
- */
- OSStatus InitializeDMATransfer(
- const IOPreparationTable *ioTablePtr,
- UInt32 logicalGranularity,
- DMATransferInfoPtr dmaTablePtr
- );
-
- /* .___________________________________________________________________________________.
- | PrepareDMATransfer |
- | |
- | Prepare the next DMA segment. |
- | Input: |
- | dmaTablePtr The DMATransferInfo record that will manage this transfer. |
- | |
- | Output: |
- | nextTransferRange Gets the segment start address and transfer length. |
- | nextIsLogical TRUE if this is a logical address. |
- | |
- | Result: |
- | noErr Normal |
- | paramErr Programming bug. |
- | eofErr Nothing more to transfer. |
- | |
- | Notes: |
- | |
- | eofErr is a normal status results. They should be replaced by |
- | by private error codes. |
- | |
- | If logical addresses are needed, the PrepareMemoryForIO must provide a "minimal |
- | logical mapping" table. |
- .___________________________________________________________________________________.
- */
- OSStatus PrepareDMATransfer(
- DMATransferInfoPtr dmaTablePtr,
- AddressRange *nextTransferRange,
- Boolean *nextIsLogical
- );
-
- /*
- * These macros are useful for DMA preparation.
- */
- /* .___________________________________________________________________________________.
- | NextPageIsContiguous |
- | |
- | TRUE if the page following this one is physically contiguous with this page. |
- | |
- | Input: |
- | map The physical map table. |
- | i The current location in the table. |
- | |
- | Result: |
- | TRUE if the pages are contiguous. |
- .___________________________________________________________________________________.
- */
- #define NextPageIsContiguous(map, i) (NextPageBaseAddress((map)[i]) == (map)[(i) + 1])
-
- /* .___________________________________________________________________________________.
- | NextPageBaseAddress |
- | |
- | Compute the base of the page that follows this page. This is needed to determine |
- | whether a logical address range is stored in a contiguous physical address range. |
- | |
- | Input: |
- | theAddress The start of the physical area. |
- | |
- | Result: |
- | The start of the next physical page. |
- .___________________________________________________________________________________.
- */
- #define NextPageBaseAddress(theAddress) \
- ((PhysicalAddress) PageBaseAddress((UInt32) (theAddress) + gPageSize))
-
- /* .___________________________________________________________________________________.
- | PageBaseAddress |
- | |
- | Return the base of the page that contains the argument. |
- | |
- | Input: |
- | theAddress The start of the physical area. |
- | |
- | Result: |
- | The start of physical page that contains this address. |
- .___________________________________________________________________________________.
- */
- #define PageBaseAddress(theAddress) ((theAddress) & ~gPageMask)
-
- /* .___________________________________________________________________________________.
- | PageOffset |
- | |
- | Return the position of this address within its page. . |
- | |
- | Input: |
- | theAddress The start of the logical or physical area. |
- | |
- | Result: |
- | The offset of the area within the physical page. |
- .___________________________________________________________________________________.
- */
- #define PageOffset(theAddress) ((theAddress) & gPageMask)
-
- #endif /* __DMATransfer__ */
-
-